import clutter, gobject, gtk

class Texture(clutter.Texture):
    # TODO: add http src support (via gtk.gdk.PixbufLoader)
    def __init__(self, path=None, uri=None):
        clutter.Texture.__init__(self)
        if path is not None:
            self.set_pixbuf(self.create_pixbuf_from_file(path))
        elif uri is not None:
            raise NotImplementedError('TODO: http src support via gtk.gdk.PixbufLoader')

    def get_clone(self):
        return CloneTexture(self)

    @classmethod
    def create_pixbuf_from_file (cls, path):
        open(path , 'r') # test file existence and permission to read
        try:
            pixbuf = gtk.gdk.pixbuf_new_from_file(path)
        except gobject.GError:
            raise TextureError("Gtk was unable to create a pixbuf from %s" %path)
        return pixbuf

    def get_prefered_size(self):
        return self.get_abs_size()

    def get_minimal_size(self):
        return 1, 1

    def set_from_file(self, path=None):
        if path is not None:
            new_pixbuf = Texture.create_pixbuf_from_file(path)
            self.set_pixbuf(new_pixbuf)

class ImageButton(Texture):
    '''
    Button widget represented by a picture. This is simply a texture which is
    reactive to click events.
    
    The click action is in fact defined here by the button press event.
    
    Sizing:
      It behaves like a basic Texture instance.
    
    :IVariables:
      on_click_callback : function
        The handler function which will be used on button click. Set to None if
        no function to call. The handler function must accept an argument which
        will reference the button itself.
    '''

    def __init__(self, path=None, uri=None, callback=None, release_cb=None):
        '''
        :Parameters:
          path : string
            A path string to the image file.
          uri : string
            A uri string to the image file.
          callback : function
            This handler function is called when the button is clicked (see
            `ImageButton.on_click_callback` attribute description for more info).
        
        ``path`` and ``uri`` are inherited from Texture constructor.
        '''
        Texture.__init__(self, path=path, uri=uri)
        self.set_reactive(True)
        self.on_click_callback = callback
        self.connect("button-press-event", self.click)
        if release_cb is not None:
            self.connect("button-release-event", release_cb)

    def click(self, source=None, event=None):
        '''
        Call this method to simulate a button click event. Handler function, if
        defined will be called back. Arguments are useless, only kept for
        clutter support.
        '''
        if self.on_click_callback is not None:
            self.on_click_callback(self)
        else:
            logger.warning("%s pressed, but no callback set", self.__class__.__name__)

